//////////////////////////////////////////////////////////////////////////////////
//                                                                              //
//  This file is part of the buola project (https://code.google.com/p/buola/).  //
//                                                                              //
//  Copyright(c) 2007-2012 Xavi Gratal                                          //
//  gratal AT gmail DOT com                                                     //
//                                                                              //
//  Buola is free software: you can redistribute it and/or modify               //
//  it under the terms of the GNU General Public License as published by        //
//  the Free Software Foundation, either version 3 of the License, or           //
//  (at your option) any later version.                                         //
//                                                                              //
//  Buola is distributed in the hope that it will be useful,                    //
//  but WITHOUT ANY WARRANTY; without even the implied warranty of              //
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               //
//  GNU General Public License for more details.                                //
//                                                                              //
//  You should have received a copy of the GNU General Public License           //
//  along with buola.  If not, see <http://www.gnu.org/licenses/>.              //
//                                                                              //
//////////////////////////////////////////////////////////////////////////////////

#include <buola/image.h>

#include <buola/image/cfontconfig.h>

namespace buola { namespace img {

std::unordered_map<CFontInfo,FcPattern*> CFontConfig::mMap;
bool CFontConfig::mFcInit=false;

void CFontConfig::Init()
{
    if(!mFcInit)
    {
        if(!FcInit())
            throw XInternal(I18N("can't initialize fontconfig"));
        mFcInit=true;
    }
}

FcPattern *CFontConfig::GetPattern(const CFontInfo &pInfo)
{
    FcPattern *lPattern=mMap[pInfo];

    if(!lPattern)
    {
        lPattern=CreatePattern(pInfo);
        mMap[pInfo]=lPattern;
    }

    return lPattern;
}

FcPattern *CFontConfig::CreatePattern(const CFontInfo &pInfo)
{
    Init();

    FcPattern *lPattern=FcPatternCreate();

    if(pInfo.GetValid()&CFontInfo::VALID_FAMILY)
    {
        FcPatternAddString(lPattern,FC_FAMILY,
                            (const FcChar8*)pInfo.GetFamily().c_str());
    }
    if(pInfo.GetValid()&CFontInfo::VALID_STYLE)
    {
        FcPatternAddString(lPattern,FC_STYLE,
                            (const FcChar8*)pInfo.GetStyle().c_str());
    }
    if(pInfo.GetValid()&CFontInfo::VALID_SLANT)
    {
        FcPatternAddInteger(lPattern,FC_SLANT,(int)pInfo.GetSlant());
    }
    if(pInfo.GetValid()&CFontInfo::VALID_WEIGHT)
    {
        FcPatternAddInteger(lPattern,FC_WEIGHT,(int)pInfo.GetWeight());
    }
    if(pInfo.GetValid()&CFontInfo::VALID_SIZE)
    {
        FcPatternAddDouble(lPattern,FC_SIZE,pInfo.GetSize());
    }
    if(pInfo.GetValid()&CFontInfo::VALID_WIDTH)
    {
        FcPatternAddInteger(lPattern,FC_WIDTH,pInfo.GetWidth());
    }
    if(pInfo.GetValid()&CFontInfo::VALID_ASPECT)
    {
        FcPatternAddDouble(lPattern,FC_ASPECT,pInfo.GetAspect());
    }
    if(pInfo.GetValid()&CFontInfo::VALID_PIXELSIZE)
    {
        FcPatternAddDouble(lPattern,FC_PIXEL_SIZE,pInfo.GetPixelSize());
    }
    if(pInfo.GetValid()&CFontInfo::VALID_SPACING)
    {
        FcPatternAddInteger(lPattern,FC_SPACING,pInfo.GetSpacing());
    }
    if(pInfo.GetValid()&CFontInfo::VALID_FOUNDRY)
    {
        FcPatternAddString(lPattern,FC_FOUNDRY,
                            (const FcChar8*)pInfo.GetFoundry().c_str());
    }
    if(pInfo.GetValid()&CFontInfo::VALID_ANTIALIAS)
    {
        FcPatternAddBool(lPattern,FC_ANTIALIAS,pInfo.GetAntialias());
    }
    if(pInfo.GetValid()&CFontInfo::VALID_DPI)
    {
        FcPatternAddDouble(lPattern,FC_DPI,pInfo.GetDPI());
    }
    if(pInfo.GetValid()&CFontInfo::VALID_ANGLE)
    {
        double lAngle=pInfo.GetAngle()*M_PI/180.0;
        FcMatrix lMatrix=
        {
            cos(lAngle),    -sin(lAngle),
            sin(lAngle),    cos(lAngle)
        };
        FcPatternAddMatrix(lPattern,FC_MATRIX,&lMatrix);
    }

    FcDefaultSubstitute(lPattern);
//    FcConfigSubstitute(nullptr,lPattern,FcMatchFont);
    FcConfigSubstitute(nullptr,lPattern,FcMatchPattern);

    return lPattern;
}

/*namespace img*/ } /*namespace buola*/ }
